package judesart.app.client.ui.admin.project;

import judesart.app.client.controller.ProjectController;
import judesart.app.client.controller.ProjectControllerAsync;
import judesart.app.client.widget.TopInfo;
import judesart.app.domain.Project;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.HtmlEditor;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class ProjectDetailsPanel extends Composite {
    ProjectControllerAsync projectController = GWT.create(ProjectController.class);
    private final SketchsPanel sketchsPanel;

    private Project project = new Project();
    private TextField<String> txtfldTitle;
    private FormPanel frmpnlBasicinfoform;
    private HtmlEditor htmldtrDescription;
    private final TabItem tbtmSkechs;
    private final TabItem tbtmPhotos;
    private final TabItem tbtmArtworks;
    private final TabItem tbtmNotes;
    private final PhotosPanel photosPanel;
    private final ArtworksPanel artworksPanel;
    private final NotesPanel notesPanel;

    public ProjectDetailsPanel() {

        ContentPanel cntntpnlProject = new ContentPanel();
        cntntpnlProject.setHeading("Project");
        cntntpnlProject.setCollapsible(false);

        TabPanel tabPanel = new TabPanel();
        tabPanel.setSize("800", "520");

        TabItem tbtmBasicInfo = new TabItem("Basic Info");
        initBasicInfoForm();
        tbtmBasicInfo.add(frmpnlBasicinfoform);
        tabPanel.add(tbtmBasicInfo);

        tbtmSkechs = new TabItem("Sketchs");
        tbtmSkechs.setEnabled(false);

        sketchsPanel = new SketchsPanel(new Project());
        tbtmSkechs.add(sketchsPanel);
        tabPanel.add(tbtmSkechs);

        tbtmPhotos = new TabItem("Photos");
        tbtmPhotos.setEnabled(false);

        photosPanel = new PhotosPanel(new Project());
        tbtmPhotos.add(photosPanel);
        tabPanel.add(tbtmPhotos);

        tbtmArtworks = new TabItem("Artworks");
        tbtmArtworks.setEnabled(false);
        artworksPanel = new ArtworksPanel(new Project());
        tbtmArtworks.add(artworksPanel);

        tabPanel.add(tbtmArtworks);

        tbtmNotes = new TabItem("Notes");
        tbtmNotes.setEnabled(false);
        notesPanel = new NotesPanel(new Project());
        tbtmNotes.add(notesPanel);
        tabPanel.add(tbtmNotes);

        cntntpnlProject.add(tabPanel);
        initComponent(cntntpnlProject);
        cntntpnlProject.setSize("800", "510");
    }

    private void initBasicInfoForm() {
        frmpnlBasicinfoform = new FormPanel();
        frmpnlBasicinfoform.setHeaderVisible(false);
        frmpnlBasicinfoform.setSize("798", "345");
        frmpnlBasicinfoform.setHeading("BasicInfoForm");
        frmpnlBasicinfoform.setButtonAlign(HorizontalAlignment.CENTER);
        FormLayout flFrmpnlBasicinfoform = new FormLayout();
        flFrmpnlBasicinfoform.setDefaultWidth(600);
        flFrmpnlBasicinfoform.setLabelAlign(LabelAlign.TOP);
        flFrmpnlBasicinfoform.setLabelSeparator("");
        frmpnlBasicinfoform.setLayout(flFrmpnlBasicinfoform);

        txtfldTitle = new TextField<String>();
        txtfldTitle.setAllowBlank(false);
        frmpnlBasicinfoform.add(txtfldTitle);
        txtfldTitle.setFieldLabel("Title");

        htmldtrDescription = new HtmlEditor();
        htmldtrDescription.setHeight("268px");
        frmpnlBasicinfoform.add(htmldtrDescription, new FormData("100%"));
        htmldtrDescription.setFieldLabel("Description");
        Button btnDelete = new Button("Delete");
        frmpnlBasicinfoform.addButton(btnDelete);

        btnDelete.addListener(Events.Select, new Listener<ButtonEvent>() {
            @Override
            public void handleEvent(ButtonEvent be) {
                delete();
            }
        });

        Button btnSave = new Button("Save");
        frmpnlBasicinfoform.addButton(btnSave);

        Button btnCancel = new Button("Cancel");
        frmpnlBasicinfoform.addButton(btnCancel);

        btnSave.addListener(Events.Select, new Listener<ButtonEvent>() {
            public void handleEvent(ButtonEvent e) {
                save();
            }
        });
        btnCancel.addListener(Events.Select, new Listener<ButtonEvent>() {
            public void handleEvent(ButtonEvent e) {
                cancel();
            }
        });
    }

    protected void open(final Long projectId) {
        if (projectId == null) {
            setProject(new Project());
        } else {
            projectController.getProject(projectId,
                    new AsyncCallback<Project>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            Log.error("Error getting project [" + projectId
                                    + "].", caught);
                            TopInfo.display("Error", "Unable to get project.");
                        }

                        @Override
                        public void onSuccess(Project result) {
                            setProject(result);
                        }
                    });
        }
    }

    private void save() {
        project.setTitle(txtfldTitle.getValue());
        project.setDescription(htmldtrDescription.getValue());

        if (project.getId() == null) {
            projectController.createProject(project,
                    new AsyncCallback<Project>() {

                        @Override
                        public void onSuccess(Project result) {
                            setProject(result);
                            TopInfo.display("Info", "Project saved.");
                        }

                        @Override
                        public void onFailure(Throwable caught) {
                            Log.error("Error creating project.", caught);
                            TopInfo.display("Error", "Unable to save project.");
                        }
                    });
        } else {
            projectController.updateProject(project,
                    new AsyncCallback<Project>() {

                        @Override
                        public void onSuccess(Project result) {
                            setProject(result);
                            TopInfo.display("Info", "Project saved.");
                        }

                        @Override
                        public void onFailure(Throwable caught) {
                            Log.error("Error saving project.", caught);
                            TopInfo.display("Error", "Unable to save project.");
                        }
                    });
        }

    }

    private void setProject(Project project) {
        this.project = project;
        boolean isNew = project.getId() == null;
        tbtmSkechs.setEnabled(!isNew);
        tbtmPhotos.setEnabled(!isNew);
        tbtmArtworks.setEnabled(!isNew);
        tbtmNotes.setEnabled(!isNew);
        txtfldTitle.setValue(project.getTitle());
        htmldtrDescription.setValue(project.getDescription());
        sketchsPanel.openProject(project);
        photosPanel.openProject(project);
        artworksPanel.openProject(project);
        notesPanel.openProject(project);
    }

    private void delete() {
        if (project.getId() == null) {
            setProject(new Project());
            cancel();
        } else {
            projectController.deleteProject(project.getId(),
                    new AsyncCallback<Void>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            Log.error("Error deleting project ["
                                    + project.getId() + "].", caught);
                            TopInfo.display("Error",
                                    "Unable to delete project.");
                        }

                        @Override
                        public void onSuccess(Void result) {
                            TopInfo.display("Info", "Project deleted");
                            cancel();
                        }
                    });
        }
    }

    private void cancel() {

    }
}
